#pragma once

#include "loirey_CachePool.h"

using namespace loirey;

void CCacheManager::myInit(size_t CacheSize, size_t ItemAmount)
{
	this->CacheSize = CacheSize;
	this->ItemAmount = ItemAmount;
	c2i.Resize(CacheSize);
	i2c.Resize(ItemAmount);
	Clear();
}

void CCacheManager::Clear()
{
	__EmptyIndex = 0;
	c2i.Fill(-1);
	i2c.Fill(-1);
}

void CCacheManager::IncreaseItemAmountBy(size_t Amount)
{
	if (Amount<1) return;
	this->ItemAmount += Amount;
	i2c.Resize(this->ItemAmount, -1);
}

void CCacheManager::ErasePosition(__int64 PositionIndex)
{
	if (PositionIndex<0 || PositionIndex>=(__int64)CacheSize) return;
	__int64 i = c2i.pElement[PositionIndex];
	c2i.pElement[PositionIndex] = -1;
	if (i >= 0)
		i2c.pElement[i] = -1;
}

__int64 CCacheManager::FindItem(__int64 ItemIndex)
{
	if (ItemIndex<0 || ItemIndex>=(__int64)ItemAmount)
		return -1;
	else
		return i2c.pElement[ItemIndex];
}

void CCacheManager::RemoveItem(__int64 ItemIndex)
{
	ErasePosition(FindItem(ItemIndex));
}

__int64 CCacheManager::GetItemPosition(__int64 ItemIndex, __int64& DstLastItemIndex)
{
	if (ItemIndex<0 || ItemIndex>=(__int64)ItemAmount)
	{
		DstLastItemIndex = -1;
		return -1;
	}
	__int64 c = FindItem(ItemIndex);
	if (c >= 0)
	{
		DstLastItemIndex = ItemIndex;
		return c;
	}
	if (__EmptyIndex < (__int64)CacheSize)
	{
		DstLastItemIndex = -1;
		c = __EmptyIndex++;
	}
	else
	{
		c = SelectRoomToKick(ItemIndex);
		DstLastItemIndex = c2i.pElement[c];
		ErasePosition(c);
	}
	c2i.pElement[c] = ItemIndex;
	i2c.pElement[ItemIndex] = c;
	return c;
}

__int64 CRandomCacheManager::SelectRoomToKick(__int64 NewItemIndex)
{
	return CMyRandom::NextInt64(CacheSize);
}

